package edu.zjucst.spb.service.impl;

import edu.zjucst.spb.domain.entity.Stage;
import edu.zjucst.spb.domain.vo.flow.FlowGroupQueryVO;
import edu.zjucst.spb.domain.vo.flow.joinParty.MyProcessTaskVO;
import edu.zjucst.spb.enums.FlowProcessExceptionEnum;
import edu.zjucst.spb.exception.BizException;
import edu.zjucst.spb.pkg.flow.stage.StageCheckComponent;
import edu.zjucst.spb.service.BranchService;
import edu.zjucst.spb.service.JoinPartyFlowService;
import edu.zjucst.spb.service.StageService;
import edu.zjucst.spb.util.converMapper.FlowBuildConvertMapper;
import edu.zjucst.spb.util.converMapper.JoinPartyConvertMapper;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.idm.api.Group;
import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZlunYan
 * @description
 * @create 2023-11-30
 */

@Service
public class JoinPartyFlowServiceImpl implements JoinPartyFlowService {

    private static final String joinPartyProcessName = "test";


    @Autowired
    private IdentityService identityService;


    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private StageService stageService;

    @Override
    public void startProcess(String userId, String branchName) {
        // 检查是否年满18 是否为共青团员 党支部信息是否正确
        Map<String, Object> variables = new HashMap<>();

        Stage stage = stageService.getStageByUserId(userId);
        if (stage == null)
            throw new BizException(FlowProcessExceptionEnum.USER_ID_NOT_EXIST.getCode(), FlowProcessExceptionEnum.USER_ID_NOT_EXIST.getDescription());
        if (stage.getProcessId() != null)
            throw new BizException(FlowProcessExceptionEnum.MULTIPLE_APPLICATION.getCode(), FlowProcessExceptionEnum.MULTIPLE_APPLICATION.getDescription());
        if (!StageCheckComponent.checkAdultAndLeagueMember(stage))
            throw new BizException(FlowProcessExceptionEnum.QUALIFICATIONS_FAIL.getCode(), FlowProcessExceptionEnum.QUALIFICATIONS_FAIL.getDescription());

        variables.put("userId", userId);

        Group group = identityService.createGroupQuery().groupName(branchName).singleResult();
        if (group == null)
            throw new BizException(FlowProcessExceptionEnum.BRANCH_GROUP_NOT_EXIST.getCode(), FlowProcessExceptionEnum.BRANCH_GROUP_NOT_EXIST.getDescription());

        variables.put("group", group.getId());

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(joinPartyProcessName, variables);
        System.out.println("processInstance = " + processInstance);


        stage.setProcessId(processInstance.getProcessInstanceId());
        stageService.updateStageByUserId(stage, userId);
    }

    @Override
    public MyProcessTaskVO queryMyCreateProcess(Integer pageNumber, Integer pageSize, String userId) {
//        Task task = new TaskEntityImpl();


        Stage stage = stageService.getStageByUserId(userId);
        if (stage == null)
            throw new BizException(FlowProcessExceptionEnum.USER_ID_NOT_EXIST.getCode(), FlowProcessExceptionEnum.USER_ID_NOT_EXIST.getDescription());

//        return taskService.createTaskQuery().processInstanceId(stage.getProcessId()).active().list();
        MyProcessTaskVO vo = new MyProcessTaskVO();
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(stage.getProcessId()).active().listPage((pageNumber-1) * pageSize, pageSize);

        vo.setTaskList(JoinPartyConvertMapper.INSTANCE.taskConvertMyProcessTask(tasks));
        vo.setPages((identityService.createGroupQuery().count() + pageSize - 1)/pageSize);
        vo.setCurrent(pageNumber.longValue());
        vo.setPageSize(pageSize.longValue());
        return vo;
    }

    @Override
    public MyProcessTaskVO queryMyTODOProcess(Integer pageNumber, Integer pageSize, String groupName) {
//        return taskService.createTaskQuery().taskCandidateOrAssigned(userId).active().list();
        Group group = identityService.createGroupQuery().groupName(groupName).singleResult();
        if (group == null)
            throw new BizException(FlowProcessExceptionEnum.BRANCH_GROUP_NOT_EXIST.getCode(), FlowProcessExceptionEnum.BRANCH_GROUP_NOT_EXIST.getDescription());

//        return taskService.createTaskQuery().taskCandidateGroup(group.getId()).active().list();
        MyProcessTaskVO vo = new MyProcessTaskVO();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(group.getId()).active().listPage((pageNumber-1) * pageSize, pageSize);

        vo.setTaskList(JoinPartyConvertMapper.INSTANCE.taskConvertMyProcessTask(tasks));
        vo.setPages((identityService.createGroupQuery().count() + pageSize - 1)/pageSize);
        vo.setCurrent(pageNumber.longValue());
        vo.setPageSize(pageSize.longValue());
        return vo;
    }

//    @Override
//    public void simpleCompleteTask(String processId, boolean accept) {
//        Task task = taskService.createTaskQuery().processInstanceId(processId).active().singleResult();
//        if (task != null) {
//            Map<String, Object> v = new HashMap<>();
//            v.put("accept", accept);
//
//            taskService.complete(task.getId(), v);
//        }
//    }

    @Override
    public void simpleCompleteTaskByTaskId(String taskId, boolean accept) {
        Task task = taskService.createTaskQuery().taskId(taskId).active().singleResult();
        if (task == null)
            throw new BizException(FlowProcessExceptionEnum.TASK_NOT_EXIST.getCode(), FlowProcessExceptionEnum.TASK_NOT_EXIST.getDescription());

        //  这个好像只能设置全局变量
//            taskService.setVariable(taskId, "accept", true);

        Map<String, Object> v = new HashMap<>();
        v.put("accept", true);

        taskService.complete(taskId,v);
    }

    @Override
    public void simpleDeleteProcess(String processId, String reason) {
        runtimeService.deleteProcessInstance(processId, reason);
    }
}
